package practice6;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class P2696 {

    static int N,M,K;           //N张票据,最大报销金额为M,票据时间差要>=K
    static int[][] arr=new int[1010][2];                        //第一行存储票据天数,第二行存储票据金额
    static int[] day={0,31,28,31,30,31,30,31,31,30,31,30,31};   //每个月的天数
    static boolean[][] dp=new boolean[1010][5010];      //表示前i张票据能够构成j金额的报销

    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);
        N=sc.nextInt();
        M=sc.nextInt();
        K=sc.nextInt();
        for(int i=1;i<=12;i++){
            day[i]+=day[i-1];       //构造前缀和,用于计算天数
        }
        for(int i=1;i<=N;i++){
            int m=sc.nextInt();
            int d=sc.nextInt();
            int v=sc.nextInt();
            arr[i][0]=day[m-1]+d;
            arr[i][1]=v;
        }
        //按照时间排序
        Arrays.sort(arr,1,N+1, Comparator.comparing(a->a[0]));
        //初始化
        dp[0][0]=true;
        int max=0;      //能报销的最大金额
        int number=0;   //不与当前票据产生冲突的最大行数(也是数量)
        for(int i=1;i<=N;i++){
            //找到不与当前票据产生冲突的最大行数
            while(arr[i][0]-arr[number+1][0]>=K){
                number++;
            }
            for(int j=0;j<=M;j++){
                dp[i][j]=dp[i-1][j];        //不转移时的赋值
                //判断能否转移
                if(j-arr[i][1]>=0 && dp[number][j-arr[i][1]]){
                    dp[i][j]=true;
                    max=Math.max(max,j);
                }
            }
        }
        System.out.println(max);
    }

}
